{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Waveguide Bend Optimization\n",
    "\n",
    "In this tutorial, we'll examine how we can use Meep's adjoint solver to optimize for a particular design criteria. Specifcally, we'll maximize the transmission around a silicon waveguide bend. This tutorial will illustrate the adjoint solver's ability to quickly calculate gradients for objective functions with multiple objective quantities.\n",
    "\n",
    "To begin, we'll import meep, our adjoint module, `autograd` (as before) and we will also import `nlopt`, a nonlinear optimization package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using MPI version 3.1, 1 processes\n"
     ]
    }
   ],
   "source": [
    "import meep as mp\n",
    "import meep.adjoint as mpa\n",
    "import numpy as np\n",
    "from autograd import numpy as npa\n",
    "import nlopt\n",
    "from matplotlib import pyplot as plt\n",
    "mp.quiet(quietval=True)\n",
    "Si = mp.Medium(index=3.4)\n",
    "SiO2 = mp.Medium(index=1.44)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we'll build a 90 degree bend waveguide with a design region that is 1 micron by 1 micron. We'll discretize our region into a 10 x 10 grid (100 total parameters). We'll send in a narrowband gaussian pulse centered at 1550 nm. We'll also use the same objective function and optimizer object as before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "resolution = 20\n",
    "\n",
    "Sx = 6\n",
    "Sy = 5\n",
    "cell_size = mp.Vector3(Sx,Sy)\n",
    "\n",
    "pml_layers = [mp.PML(1.0)]\n",
    "\n",
    "fcen = 1/1.55\n",
    "width = 0.2\n",
    "fwidth = width * fcen\n",
    "source_center  = [-1.5,0,0]\n",
    "source_size    = mp.Vector3(0,2,0)\n",
    "kpoint = mp.Vector3(1,0,0)\n",
    "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n",
    "source = [mp.EigenModeSource(src,\n",
    "                    eig_band = 1,\n",
    "                    direction=mp.NO_DIRECTION,\n",
    "                    eig_kpoint=kpoint,\n",
    "                    size = source_size,\n",
    "                    center=source_center)]\n",
    "\n",
    "design_region_resolution = 10\n",
    "Nx = design_region_resolution\n",
    "Ny = design_region_resolution\n",
    "\n",
    "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),SiO2,Si,grid_type='U_MEAN')\n",
    "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(1, 1, 0)))\n",
    "\n",
    "\n",
    "geometry = [\n",
    "    mp.Block(center=mp.Vector3(x=-Sx/4), material=Si, size=mp.Vector3(Sx/2, 0.5, 0)), # horizontal waveguide\n",
    "    mp.Block(center=mp.Vector3(y=Sy/4), material=Si, size=mp.Vector3(0.5, Sy/2, 0)),  # vertical waveguide\n",
    "    mp.Block(center=design_region.center, size=design_region.size, material=design_variables), # design region\n",
    "    mp.Block(center=design_region.center, size=design_region.size, material=design_variables,\n",
    "             e1=mp.Vector3(x=-1).rotate(mp.Vector3(z=1), np.pi/2), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), np.pi/2))\n",
    "]\n",
    "\n",
    "sim = mp.Simulation(cell_size=cell_size,\n",
    "                    boundary_layers=pml_layers,\n",
    "                    geometry=geometry,\n",
    "                    sources=source,\n",
    "                    eps_averaging=False,\n",
    "                    resolution=resolution)\n",
    "\n",
    "TE_top = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(0,1,0),size=mp.Vector3(x=2)),mode=1)\n",
    "ob_list = [TE_top]\n",
    "\n",
    "def J(alpha):\n",
    "    return npa.abs(alpha) ** 2\n",
    "\n",
    "opt = mpa.OptimizationProblem(\n",
    "    simulation=sim,\n",
    "    objective_functions=J,\n",
    "    objective_arguments=ob_list,\n",
    "    design_regions=[design_region],\n",
    "    fcen=fcen,\n",
    "    df = 0,\n",
    "    nf = 1,\n",
    "    decay_fields=[mp.Ez]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As before, we'll visualize everything to ensure our monitors, boundary layers, and geometry are drawn correctly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x0 = 0.5*np.ones((Nx*Ny,))\n",
    "opt.update_design([x0])\n",
    "\n",
    "opt.plot2D(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now define a cost function wrapper that we can feed into our `nlopt` optimizer. `nlopt` expects a python function where the gradient is passed in place. In addition, we'll update a list with every objective function call so we can track the cost function evolution each iteration.\n",
    "\n",
    "Notice the `opt` adjoint solver object requires we pass our numpy array of design parameters within an additional list. This is because the adjoint solver can solve for multiple design regions simultaneously. It's useful to break up each region's parameters into indvidual numpy arrays. In this simple example, we only have one design region."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "evaluation_history = []\n",
    "sensitivity = [0]\n",
    "def f(x, grad):\n",
    "    f0, dJ_du = opt([x])\n",
    "    if grad.size > 0:\n",
    "        grad[:] = np.squeeze(dJ_du)\n",
    "    evaluation_history.append(np.real(f0))\n",
    "    sensitivity[0] = dJ_du\n",
    "    return np.real(f0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can set up the actual optimizer engine. We'll select the Method of Moving Asymptotes because it's a gradient based method that allows us to specify linear and nonlinear constraints. For now, we'll simply bound our parameters between 0 and 1.\n",
    "\n",
    "We'll tell our solver to maximize (rather than minimize) our cost function, since we are trying to maximize the power transmission around the bend.\n",
    "\n",
    "We'll also tell the optimizer to stop after 10 function calls. This will keep the wait time short and demonstrate how powerful the adjoint solver is."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n"
     ]
    }
   ],
   "source": [
    "algorithm = nlopt.LD_MMA\n",
    "n = Nx * Ny\n",
    "maxeval = 10\n",
    "\n",
    "solver = nlopt.opt(algorithm, n)\n",
    "solver.set_lower_bounds(0)\n",
    "solver.set_upper_bounds(1)\n",
    "solver.set_max_objective(f)\n",
    "solver.set_maxeval(maxeval)\n",
    "x = solver.optimize(x0);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that the solver is done running, we can evaluate our progress."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "plt.plot(evaluation_history,'o-')\n",
    "plt.grid(True)\n",
    "plt.xlabel('Iteration')\n",
    "plt.ylabel('FOM')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can update our optimization object and visualize the results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "opt.update_design([x])\n",
    "opt.plot2D(True,plot_monitors_flag=False,output_plane=mp.Volume(center=(0,0,0),size=(2,2,0)))\n",
    "plt.axis(\"off\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We quickly see that the solver improves the design each iteration, but because of the way we chose to formulate our cost function, it's difficult to quantify our results. After all, how good is a figure of merit (FOM) of 70?\n",
    "\n",
    "To overcome this, we'll slightly modify our objective function to include an extra monitor just after the source. This monitor will track however much power is transmitted into the waveguide. We can then normalize the upper monitor's response by this parameter:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "TE0 = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(-1,0,0),size=mp.Vector3(y=2)),mode=1)\n",
    "ob_list = [TE0,TE_top]\n",
    "\n",
    "def J(source,top):\n",
    "    return npa.abs(top/source) ** 2\n",
    "\n",
    "opt.objective_functions = [J]\n",
    "opt.objective_arguments = ob_list\n",
    "opt.update_design([x0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll refresh our solver and try optimizing again:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5\n",
      " 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n",
      "Starting forward run...\n",
      "Starting adjoint run...\n",
      "Calculating gradient...\n"
     ]
    }
   ],
   "source": [
    "evaluation_history = []\n",
    "solver = nlopt.opt(algorithm, n)\n",
    "solver.set_lower_bounds(0)\n",
    "solver.set_upper_bounds(1)\n",
    "solver.set_max_objective(f)\n",
    "solver.set_maxeval(maxeval)\n",
    "x = solver.optimize(x0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can view our results and normalize the FOM as the percent power transmission."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "plt.plot(np.array(evaluation_history)*100,'o-')\n",
    "plt.grid(True)\n",
    "plt.xlabel('Iteration')\n",
    "plt.ylabel('Transmission (%)')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We once again clearly see great improvement, from about 5% transmission to about 85%, after just 10 iterations! We noticed that the cost function is much more complicated now as the optimizer no longer monotonically improves as it did before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Achieved an improvement of 28.0x\n"
     ]
    }
   ],
   "source": [
    "improvement = max(evaluation_history) / min(evaluation_history)\n",
    "print(\"Achieved an improvement of {0:1.1f}x\".format(improvement))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can visualize our new geometry. We see that the design region naturally connected the two waveguide segements in a bend fashion and has placed several other distinctive features around the curve."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "opt.update_design([x])\n",
    "opt.plot2D(True,plot_monitors_flag=False,output_plane=mp.Volume(center=(0,0,0),size=(2,2,0)))\n",
    "plt.axis(\"off\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also visualize the sensitivity to see which geometric areas are most sensitive to perturbations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPUAAAD4CAYAAAA0L6C7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAAMDUlEQVR4nO3dTYxV9RnH8d/v3mGAmRGxr6lghMRGS2yMZEJRkzb1JdXa1C6alCbatBs2fbFNk0a7cdOlbXRh2hBtNzU1KXVhjPUl0S7apsQRMAq0apAKCIXGABYZhmGeLmZMKDDcM5f/v2fmyfeTmDBzrw9PYL6cO2fOnHFECEAenbYXAFAWUQPJEDWQDFEDyRA1kMxAjaGDnaWxdGBZ+cGnT5efKSmmporP9JLFxWfWFCdPVpnrTp3jRpwu/3dWS40/gxNT/9FEjPt8j1WJeunAMt34yQ3F504dOVp8piRNnRgvPrO7anXxmdOD60Qy9cbuKnM7Q0NV5p5+//3yQyt9ebczcknxmX/7z1Oz/37FfzcArSJqIBmiBpIhaiAZogaSIWogmUZR277d9j9sv2X7vtpLAehfz6htdyU9IukOSWskfdP2mtqLAehPkyP1OklvRcTuiJiQ9ISku+quBaBfTaJeIWnvGW/vm3nf/7C90faY7bGJqROl9gMwR8VOlEXEpogYjYjRwc7SUmMBzFGTqPdLuuKMt1fOvA/APNQk6pclfdr2atuDkjZImv1qcgCt6vldWhExaft7kp6T1JX064jYUX0zAH1p9K2XEfGMpGcq7wKgAK4oA5IhaiAZogaSIWogGaIGkqly40GdPl3tJoE1xPpri8881TnvjR4v2uTIoipz37ttXZW5n/rLsSpzNfZ68ZHd5ZcWnylJHhkpP/REd9aHOFIDyRA1kAxRA8kQNZAMUQPJEDWQDFEDyRA1kAxRA8kQNZAMUQPJEDWQDFEDyRA1kAxRA8kQNZAMUQPJEDWQDFEDyRA1kAxRA8lUuZtoTE1p6sR4+bkV7vopSf7rq8VnDlS6M+X4F6+pMrc7EVXmTo4MVpnbueG64jMPf2ao+ExJGj44WXzm1LHZ7yrLkRpIhqiBZIgaSIaogWSIGkiGqIFkiBpIpmfUtq+w/ZLtnbZ32L73/7EYgP40ufhkUtKPI2Kr7UskvWL7hYjYWXk3AH3oeaSOiAMRsXXm1+9L2iVpRe3FAPRnTpeJ2l4l6XpJW87z2EZJGyVpiepcbgegt8YnymyPSPqDpB9GxLGzH4+ITRExGhGji7S45I4A5qBR1LYXaTroxyPiyborAbgYTc5+W9JjknZFxC/qrwTgYjQ5Ut8k6R5JN9vePvPflyvvBaBPPU+URcSfJfn/sAuAAriiDEiGqIFkiBpIhqiBZKrceNBLFqu7anXxuac6dc7X1bhJoIeHi8+UpGVb360yd/jgoSpzp78iWt74F8rfhPL45XV2XXy0/LEzLtACR2ogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIJkqdxOVJHXL/3sxObKo+ExJGv/iNcVn1rrr55HPragyd3j/R6vM7W5/s8rcpXuOFJ955YE6OXj8VPGZ3Q8mZ32MIzWQDFEDyRA1kAxRA8kQNZAMUQPJEDWQTOOobXdtb7P9dM2FAFycuRyp75W0q9YiAMpoFLXtlZLulPRo3XUAXKymR+qHJP1E0tRsT7C90faY7bGJ0x8UWQ7A3PWM2vZXJB2KiFcu9LyI2BQRoxExOtgdKrYggLlpcqS+SdJXbe+R9ISkm23/tupWAPrWM+qIuD8iVkbEKkkbJL0YEXdX3wxAX/g6NZDMnL6BNCL+JOlPVTYBUARHaiAZogaSIWogGaIGkiFqIJkqt0+Mkyc19cbu4nPfu21d8ZmS1J2I4jOHDx4qPlOqd9fPgfeOV5l79M7PVpm77I87is+cXHtV8ZmSNLinwp9tzHrFNkdqIBuiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiCZKncTdaejzlD5n1H9qb8cKz5TkiZHBovPtF18piR1t79ZZW6tu36O/H5Llbm7f7a++MzhfcVHSpKOfm1F8ZnjP5/9Y5YjNZAMUQPJEDWQDFEDyRA1kAxRA8kQNZBMo6htL7e92fbfbe+yfUPtxQD0p+nFJw9LejYivm57UFL5K0sAFNEzatuXSvq8pG9LUkRMSJqouxaAfjV5+b1a0mFJv7G9zfajtofPfpLtjbbHbI9NTI0XXxRAM02iHpC0VtIvI+J6Sccl3Xf2kyJiU0SMRsToYGdJ4TUBNNUk6n2S9kXEh1fmb9Z05ADmoZ5RR8RBSXttXz3zrlsk7ay6FYC+NT37/X1Jj8+c+d4t6Tv1VgJwMRpFHRHbJY1W3gVAAVxRBiRD1EAyRA0kQ9RAMkQNJOOIKD50mT8Sn+vcWnyuKuwqSXHDdcVnnlq2qPhMSVq650iVufHuv6rM3X3ftVXmfmTtoeIzL/tWnbvVPvPqC8VnrvvSXo29On7eW9ZypAaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogGaIGkiFqIBmiBpIhaiAZogaSIWogmaY/S2vuKtwksLv80uIzJenwZ4aKzzx++XnvCXfRrjxQ569scu1VVeYO76syVpc9VP4mgf/81SeKz5SktWPfKD7zjQ8em/UxjtRAMkQNJEPUQDJEDSRD1EAyRA0kQ9RAMo2itv0j2ztsv277d7aX1F4MQH96Rm17haQfSBqNiGsldSVtqL0YgP40ffk9IGmp7QFJQ5LerbcSgIvRM+qI2C/pQUnvSDog6WhEPH/282xvtD1me+yUTpbfFEAjTV5+XybpLkmrJV0uadj23Wc/LyI2RcRoRIwu0uLymwJopMnL71slvR0RhyPilKQnJd1Ydy0A/WoS9TuS1tsesm1Jt0jaVXctAP1q8jn1FkmbJW2V9NrM/7Op8l4A+tTom3Mj4gFJD1TeBUABXFEGJEPUQDJEDSRD1EAyRA0kU+XWlO501Bm5pPzckZHiMyVp+OBk8ZmLj9b599Ljp6rMHdxzvMrco19bUWXu1ldfKD6zxl0/JenI3uXFZ56emD1djtRAMkQNJEPUQDJEDSRD1EAyRA0kQ9RAMkQNJEPUQDJEDSRD1EAyRA0kQ9RAMkQNJEPUQDJEDSRD1EAyRA0kQ9RAMkQNJEPUQDKOiPJD7cOS/tngqR+T9O/iC9SzkPZdSLtKC2vf+bDrlRHx8fM9UCXqpmyPRcRoawvM0ULadyHtKi2sfef7rrz8BpIhaiCZtqNeaD+8fiHtu5B2lRbWvvN611Y/pwZQXttHagCFETWQTGtR277d9j9sv2X7vrb26MX2FbZfsr3T9g7b97a9UxO2u7a32X667V0uxPZy25tt/932Lts3tL3Thdj+0czHweu2f2d7Sds7na2VqG13JT0i6Q5JayR90/aaNnZpYFLSjyNijaT1kr47j3c9072SdrW9RAMPS3o2Iq6RdJ3m8c62V0j6gaTRiLhWUlfShna3OldbR+p1kt6KiN0RMSHpCUl3tbTLBUXEgYjYOvPr9zX9QVfnhy4XYnulpDslPdr2Lhdi+1JJn5f0mCRFxEREHGl3q54GJC21PSBpSNK7Le9zjraiXiFp7xlv79M8D0WSbK+SdL2kLe1u0tNDkn4iaartRXpYLemwpN/MfKrwqO3htpeaTUTsl/SgpHckHZB0NCKeb3erc3GirCHbI5L+IOmHEXGs7X1mY/srkg5FxCtt79LAgKS1kn4ZEddLOi5pPp9fuUzTryhXS7pc0rDtu9vd6lxtRb1f0hVnvL1y5n3zku1Fmg768Yh4su19erhJ0ldt79H0pzU32/5tuyvNap+kfRHx4SufzZqOfL66VdLbEXE4Ik5JelLSjS3vdI62on5Z0qdtr7Y9qOmTDU+1tMsF2bamP+fbFRG/aHufXiLi/ohYGRGrNP3n+mJEzLujiSRFxEFJe21fPfOuWyTtbHGlXt6RtN720MzHxS2ahyf2Btr4TSNi0vb3JD2n6TOIv46IHW3s0sBNku6R9Jrt7TPv+2lEPNPiTpl8X9LjM/+475b0nZb3mVVEbLG9WdJWTX9VZJvm4SWjXCYKJMOJMiAZogaSIWogGaIGkiFqIBmiBpIhaiCZ/wJjcaqbIt3FVgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(np.rot90(np.squeeze(np.abs(sensitivity[0].reshape(Nx,Ny)))));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
